package a.b.mvc6.config;

import com.alibaba.fastjson2.support.spring6.data.redis.GenericFastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.*;

import java.time.Duration;

@Configuration
@EnableRedisRepositories("a.b.mvc6.repository")
public class RedisConfig {

    @Autowired
    private Environment env;

    /**
     * 配置单独的Jedis
     * @return JedisPooled
     */
    @Bean(destroyMethod = "close")
    public JedisPooled jedisPooled(){
        HostAndPort hostAndPort = new HostAndPort("106.13.40.185", 6379);
        JedisClientConfig clientConfig = DefaultJedisClientConfig.builder()
                .resp3()
                .user("liang")
                .password("liang1997")
                .database(1)
                .clientName("JedisPooled")
                .build();
        return new JedisPooled(hostAndPort, clientConfig);
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        // 这里配置 Redis 的基本信息
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(env.getProperty("redis.url", "127.0.0.1"));
        config.setPort(Integer.parseInt(env.getProperty("redis.port", "6379")));
        config.setDatabase(Integer.parseInt(env.getProperty("redis.database", "0")));
        config.setUsername(env.getProperty("redis.username"));
        config.setPassword(env.getProperty("redis.password"));

        // 这里配置 Jedis连接池的信息
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(Integer.parseInt(env.getProperty("redis.pool.max-total", "10")));  // 最大连接数
        poolConfig.setMaxIdle(Integer.parseInt(env.getProperty("redis.pool.max-idle", "5")));   // 最大空闲连接数
        poolConfig.setMinIdle(Integer.parseInt(env.getProperty("redis.pool.min-idle", "2")));    // 最小空闲连接数
        poolConfig.setTestOnBorrow(Boolean.parseBoolean(env.getProperty("redis.pool.set-test-on-borrow", "true"))); // 连接池获取连接时测试有效性
        poolConfig.setTestOnReturn(Boolean.parseBoolean(env.getProperty("redis.pool.set-test-on-return", "true"))); // 连接池归还连接时测试有效性


        // 这里配置Jedis每个连接的属性
        JedisClientConfiguration build = JedisClientConfiguration
                .builder()
                .clientName(env.getProperty("redis.client-name", ""))
                .connectTimeout(Duration.ofMillis(Long.parseLong(env.getProperty("redis.connect-timeout", "2000"))))
                .readTimeout(Duration.ofMinutes(Long.parseLong(env.getProperty("redis.read-timeout", "2000"))))
                .usePooling()
                .poolConfig(poolConfig)
                .build();

        // 创建Jedis连接工厂
        return new JedisConnectionFactory(config, build);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 设置 key 和 value 的序列化方式
        template.setKeySerializer(StringRedisSerializer.UTF_8);  // Key 使用 StringRedisSerializer
        template.setValueSerializer(new GenericFastJsonRedisSerializer());  // Value 使用 Json 序列化器
        template.setHashKeySerializer(StringRedisSerializer.UTF_8);
        template.setHashValueSerializer(new GenericFastJsonRedisSerializer());
        template.setStringSerializer(StringRedisSerializer.UTF_8);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory);
        stringRedisTemplate.afterPropertiesSet();
        return stringRedisTemplate;
    }
}
